import py3func
from executor.key import *
from executor.abstractcmd import NonKeyCmd, NONKEY_ACTIVATE_TIME

LOG = py3func.make_logging(__file__)

class RealKeyboard:
    """ Combination of the Key types.
        'Real' means the key response to the actions --> press/release.
    """
    def __new__(cls):
        if not hasattr(cls, "singleton_instance"):
            cls.singleton_instance = super().__new__(cls)
            cls.init()
        return cls.singleton_instance  # 返回单例对象

    @classmethod
    def init(self):
        self.charKey = Key_Char()
        self.funcKey = Key_Func()
        self.modeKeys = {}  # { "shift": Key(), ... }

    def _debug_showList_modeKeys(self):
        """ A debug list, showing the modeKeys' pressing status """
        # print("The dict of modeKeys here: %s" % self.modeKeys)
        list_debug = ["Here will show the list of mode keys: \n"]
        if not self.modeKeys:
            list_debug.append("NULL dict of Mode keys")
        for key_name, key_obj in self.modeKeys.items():
            # print("key_name -->> ", key_name )
            str_cur_key = key_name + " has been pressed.\n" \
                    if key_obj.isPressed else " is released.\n"
            list_debug.append(str_cur_key)
        LOG.debug("".join(list_debug))

    def key_exec(self, key_type, key_name, key_status):
        if key_type == "key_char":
            self.charKey.update_keycode(key_name)
            self.charKey.key_exec(key_status)
        elif key_type == "key_func":
            self.funcKey.update_keycode(key_name)
            self.funcKey.key_exec(key_status)
        elif key_type == "key_mode":
            if key_name not in self.modeKeys:
                LOG.debug("A new Mode Key [%s] is created." % key_name)
                self.modeKeys[key_name] = Key_Mode(key_name)
            # self._debug_showList_modeKeys()
            self.modeKeys[key_name].key_exec(key_status)

class VirtualKeyboard(NonKeyCmd):
    def __init__(self):
        super().__init__()
        self.keyboard = RealKeyboard()
        self.list_action = []

    def key_exec(self, key_type, key_name, key_status):
        if key_status != Enum_Btn_Status["pressed"]:  # == NONKEY_ACTIVATE_TIME
            self.list_action.append(key_status)
            self.cmd_exec(key_type, key_name)
            self.list_action.clear()
        else:
            LOG.debug("VirtualKeyboard: 延缓执行")
            self.list_action.append(key_status)

    def cmd_exec(self, key_type, key_name):
        for key_status in self.list_action:
            LOG.debug("VirtualKeyboard: Execute the command together -- [%s]" % key_status)
            self.keyboard.key_exec(key_type, key_name, key_status)
